#include <RenderSubsystem/RendererFactory.h>
#include <RenderSubSystem/cvIRender.h>
#include <Logger/ILogger.h>
#include <SubSystemBase/SubSystemManager.h>
#include <RenderSubSystem/RenderSubSystem.h>
#include <RenderSubsystem/cvImmediateModeRenderer.h>



RendererFactory::RENDERER_OVERRIDES RendererFactory::override = RendererFactory::RENDERER_NOOVERRIDE;

RendererFactory::RendererFactory()
{
	//Never instantiate
	//log.critical("Trying to instantiate static class RendererFactory");
}

void RendererFactory::setRendererOverride(RENDERER_OVERRIDES new_override)
{
	RendererFactory::override = new_override;
}

cvRenderInterface::IRenderer* RendererFactory::createRenderer()
{
	ILogger* logger = 0;

	ISubSystem* renderSubSys = SubSystemManager::getInstance()->getSubSystemByName(RenderSubSystem::SUBSYSTEMNAME);
	if(renderSubSys)
	{
		logger = renderSubSys->getLogger();
	}

	if(RendererFactory::override == RendererFactory::RENDERER_NOOVERRIDE)
	{
		// Filter from top (highest/newest) features to downwards, until a match is found

		bool vaoSupport = vaoSupported();
		bool shaderSupport = shadersSupported();
		bool vboSupport = vboSupported();

		if(vaoSupport && shaderSupport)
		{
			if(logger)
			{
				logger->info("Support for VAO + shaders detected");
			}
			//return new VAOWithShadersRenderer();
		}
		else if(shaderSupport && vboSupport)
		{
			if(logger)
			{
				logger->info("Support for VBO + shaders detected");
			}
			//return new VBOWithShadersRenderer();
		}
		else if(vboSupport)
		{
			if(logger)
			{
				logger->info("Support for VBO detected");
			}
			//return new VBORenderer();
		}

		if(logger)
		{
			logger->info("Using immediate mode renderer, either the hardware doesn't support VBOs or anything better, or we just haven't implemented other renderers yet");
		}
		// No extensions, only immediate mode supported
		return new cvImmediateModeRenderer::ImmediateModeRenderer();
	}

	//Overrides
	switch(RendererFactory::override)
	{
	case RENDERER_IMMEDIATEMODE:
		if(logger)
		{
			logger->info("Using overridden renderer: ImmediateMode");
		}

		return new cvImmediateModeRenderer::ImmediateModeRenderer();
		break;
	case RENDERER_VBO:
		if(logger)
		{
			logger->info("Using overridden renderer: VBO");
		}

		//TODO: implement VBO-renderer
		return new cvImmediateModeRenderer::ImmediateModeRenderer();
		break;
	case RENDERER_VBOWITHSHADERS:
		if(logger)
		{
			logger->info("Using overridden renderer: VBO with Shaders");
		}
		//TODO: implement VBO + shaders-renderer
		return new cvImmediateModeRenderer::ImmediateModeRenderer();
		break;
	case RENDERER_VAOWITHSHADERS:
		if(logger)
		{
			logger->info("Using overridden renderer: VAO with Shaders");
		}
		//TODO: implement VAO with shaders -renderer
		return new cvImmediateModeRenderer::ImmediateModeRenderer();
		break;
	default:
		if(logger)
		{
			logger->critical("RendererFactory: Unknown override in effect");
		}
		return 0;
	}
}

bool RendererFactory::vaoSupported()
{
	//if(glewIsSupported("GL_ARB_vertex_array_object"))
	//{
		//return true;
	//}
	return false;
}

bool RendererFactory::shadersSupported()
{
	//if(glewIsSupported("GL_ARB_shader_objects") && glewIsSupported("GL_ARB_vertex_shader") && glewIsSupported("GL_ARB_fragment_shader"))
	//{
		//return true;
	//}
	return false;
}

bool RendererFactory::vboSupported()
{
	//if(glewIsSupported("GL_ARB_vertex_buffer_object"))
	//{
		//return true;
	//}
	return false;
}
